<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>浏览器 Linux 容器演示 - Python Runtime</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: #1e1e1e;
            color: #d4d4d4;
            height: 100vh;
            display: flex;
            flex-direction: column;
        }

        .header {
            background: #252526;
            padding: 15px 20px;
            border-bottom: 1px solid #3c3c3c;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .header h1 {
            font-size: 18px;
            color: #ffffff;
        }

        .header select {
            background: #3c3c3c;
            color: #d4d4d4;
            border: 1px solid #555;
            padding: 8px 15px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
        }

        .header button {
            background: #0e639c;
            color: white;
            border: none;
            padding: 8px 20px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            margin-left: 10px;
            transition: background 0.2s;
        }

        .header button:hover {
            background: #1177bb;
        }

        .header button:disabled {
            background: #555;
            cursor: not-allowed;
        }

        .container {
            display: flex;
            flex: 1;
            overflow: hidden;
        }

        .editor-section {
            flex: 1;
            display: flex;
            flex-direction: column;
            border-right: 1px solid #3c3c3c;
        }

        .editor-header {
            background: #252526;
            padding: 10px 20px;
            border-bottom: 1px solid #3c3c3c;
            font-size: 14px;
        }

        #code-editor {
            flex: 1;
            background: #1e1e1e;
            color: #d4d4d4;
            font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
            font-size: 14px;
            padding: 20px;
            border: none;
            resize: none;
            outline: none;
            line-height: 1.5;
        }

        .output-section {
            width: 40%;
            display: flex;
            flex-direction: column;
            background: #1e1e1e;
        }

        .output-header {
            background: #252526;
            padding: 10px 20px;
            border-bottom: 1px solid #3c3c3c;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .output-header button {
            background: transparent;
            color: #d4d4d4;
            border: 1px solid #555;
            padding: 5px 10px;
            border-radius: 3px;
            cursor: pointer;
            font-size: 12px;
        }

        #output {
            flex: 1;
            background: #1e1e1e;
            color: #cccccc;
            font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
            font-size: 13px;
            padding: 20px;
            overflow-y: auto;
            white-space: pre-wrap;
            word-wrap: break-word;
        }

        .loading {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: #252526;
            padding: 30px 50px;
            border-radius: 8px;
            text-align: center;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
        }

        .loading-spinner {
            border: 4px solid #3c3c3c;
            border-top: 4px solid #0e639c;
            border-radius: 50%;
            width: 40px;
            height: 40px;
            animation: spin 1s linear infinite;
            margin: 0 auto 15px;
        }

        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }

        .status-bar {
            background: #007acc;
            color: white;
            padding: 5px 20px;
            font-size: 12px;
            display: none;
        }

        .status-bar.show {
            display: block;
        }

        .error {
            color: #f48771;
        }

        .success {
            color: #4ec9b0;
        }

        .info {
            color: #9cdcfe;
        }

        .examples {
            padding: 10px 20px;
            background: #252526;
            border-bottom: 1px solid #3c3c3c;
            font-size: 12px;
        }

        .examples button {
            background: #3c3c3c;
            color: #d4d4d4;
            border: 1px solid #555;
            padding: 5px 10px;
            border-radius: 3px;
            cursor: pointer;
            margin-right: 10px;
            font-size: 12px;
        }

        .examples button:hover {
            background: #555;
        }
    </style>
</head>
<body>
    <div class="loading" id="loading">
        <div class="loading-spinner"></div>
        <div>正在加载 Python 运行时...</div>
        <div style="font-size: 12px; color: #888; margin-top: 10px;">首次加载可能需要几秒钟</div>
    </div>

    <div class="header">
        <h1>🚀 浏览器 Linux 容器演示 - Python in Browser</h1>
        <div>
            <select id="language-select">
                <option value="python">Python 3.11</option>
                <option value="javascript" disabled>JavaScript (即将支持)</option>
                <option value="rust" disabled>Rust (即将支持)</option>
            </select>
            <button id="run-btn" onclick="runCode()">▶ 运行 (Ctrl+Enter)</button>
        </div>
    </div>

    <div class="examples">
        <span style="color: #888;">示例：</span>
        <button onclick="loadExample('hello')">Hello World</button>
        <button onclick="loadExample('math')">数学计算</button>
        <button onclick="loadExample('datastructure')">数据结构</button>
        <button onclick="loadExample('numpy')">NumPy (需安装)</button>
    </div>

    <div class="status-bar" id="status-bar"></div>

    <div class="container">
        <div class="editor-section">
            <div class="editor-header">📝 代码编辑器</div>
            <textarea id="code-editor" spellcheck="false"># 欢迎使用浏览器 Python 运行时！
# 这是在浏览器中运行的真实 Python 3.11 环境

print("Hello from Python in Browser!")
print("=" * 40)

# 基础计算
result = sum(range(1, 101))
print(f"1 到 100 的和: {result}")

# 列表推导式
squares = [x**2 for x in range(1, 11)]
print(f"前 10 个平方数: {squares}")

# 字典操作
person = {
    "name": "Alice",
    "age": 25,
    "skills": ["Python", "JavaScript", "Rust"]
}
print(f"\n个人信息: {person}")

# 函数定义
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print(f"\n斐波那契数列前 10 个数:")
print([fibonacci(i) for i in range(10)])

print("\n✅ 所有测试通过！")
</textarea>
        </div>

        <div class="output-section">
            <div class="output-header">
                <span>📊 输出</span>
                <button onclick="clearOutput()">清除</button>
            </div>
            <div id="output">等待运行...</div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.js"></script>
    <script>
        let pyodide = null;
        let isReady = false;

        // 示例代码
        const examples = {
            hello: `# Hello World 示例
print("Hello, World!")
print("欢迎使用浏览器 Python 环境！")

for i in range(5):
    print(f"计数: {i + 1}")`,

            math: `# 数学计算示例
import math

print("数学常数:")
print(f"π = {math.pi}")
print(f"e = {math.e}")

print("\\n三角函数:")
angle = 45
radians = math.radians(angle)
print(f"sin({angle}°) = {math.sin(radians):.4f}")
print(f"cos({angle}°) = {math.cos(radians):.4f}")

print("\\n阶乘:")
for i in range(1, 6):
    print(f"{i}! = {math.factorial(i)}")`,

            datastructure: `# 数据结构示例
from collections import defaultdict, Counter

# 列表操作
numbers = [1, 2, 3, 4, 5]
doubled = [x * 2 for x in numbers]
print(f"原始列表: {numbers}")
print(f"翻倍后: {doubled}")

# 字典操作
word_count = Counter("hello world".split())
print(f"\\n单词计数: {word_count}")

# 集合操作
set_a = {1, 2, 3, 4, 5}
set_b = {4, 5, 6, 7, 8}
print(f"\\n集合 A: {set_a}")
print(f"集合 B: {set_b}")
print(f"交集: {set_a & set_b}")
print(f"并集: {set_a | set_b}")
print(f"差集: {set_a - set_b}")`,

            numpy: `# NumPy 示例（需要先安装）
import micropip
await micropip.install('numpy')

import numpy as np

# 创建数组
arr = np.array([1, 2, 3, 4, 5])
print(f"数组: {arr}")
print(f"平均值: {arr.mean()}")
print(f"标准差: {arr.std()}")

# 矩阵操作
matrix = np.array([[1, 2], [3, 4]])
print(f"\\n矩阵:\\n{matrix}")
print(f"转置:\\n{matrix.T}")
print(f"行列式: {np.linalg.det(matrix)}")

print("\\n✅ NumPy 运行成功！")`
        };

        // 加载 Pyodide
        async function loadPyodide() {
            try {
                showStatus('正在初始化 Python 运行时...', 'info');
                pyodide = await loadPyodide({
                    indexURL: 'https://cdn.jsdelivr.net/pyodide/v0.24.1/full/'
                });
                
                // 重定向标准输出
                await pyodide.runPythonAsync(`
                    import sys
                    from io import StringIO
                    sys.stdout = StringIO()
                    sys.stderr = StringIO()
                `);
                
                isReady = true;
                document.getElementById('loading').style.display = 'none';
                document.getElementById('run-btn').disabled = false;
                showStatus('✅ Python 运行时已就绪', 'success');
                
                setTimeout(() => {
                    document.getElementById('status-bar').classList.remove('show');
                }, 3000);
            } catch (error) {
                document.getElementById('loading').innerHTML = 
                    `<div class="error">加载失败: ${error.message}</div>`;
                showStatus('❌ 加载失败', 'error');
            }
        }

        // 运行代码
        async function runCode() {
            if (!isReady) {
                alert('Python 运行时还未准备好，请稍候...');
                return;
            }

            const code = document.getElementById('code-editor').value;
            const output = document.getElementById('output');
            const runBtn = document.getElementById('run-btn');
            
            output.textContent = '正在运行...\n';
            runBtn.disabled = true;
            showStatus('⏳ 正在执行代码...', 'info');

            const startTime = performance.now();

            try {
                // 执行代码
                await pyodide.runPythonAsync(code);
                
                // 获取输出
                const stdout = await pyodide.runPythonAsync('sys.stdout.getvalue()');
                const stderr = await pyodide.runPythonAsync('sys.stderr.getvalue()');
                
                // 清空缓冲区
                await pyodide.runPythonAsync(`
                    sys.stdout = StringIO()
                    sys.stderr = StringIO()
                `);

                const duration = (performance.now() - startTime).toFixed(2);
                
                let result = '';
                if (stdout) result += stdout;
                if (stderr) result += `\n<span class="error">${stderr}</span>`;
                result += `\n\n<span class="success">✅ 执行完成 (${duration}ms)</span>`;
                
                output.innerHTML = result;
                showStatus(`✅ 执行成功 (${duration}ms)`, 'success');
                
            } catch (error) {
                const duration = (performance.now() - startTime).toFixed(2);
                output.innerHTML = `<span class="error">❌ 错误:\n${error.message}</span>\n\n<span class="info">执行时间: ${duration}ms</span>`;
                showStatus('❌ 执行失败', 'error');
            } finally {
                runBtn.disabled = false;
                setTimeout(() => {
                    document.getElementById('status-bar').classList.remove('show');
                }, 3000);
            }
        }

        // 加载示例
        function loadExample(exampleName) {
            const editor = document.getElementById('code-editor');
            if (examples[exampleName]) {
                editor.value = examples[exampleName];
                showStatus(`📝 已加载示例: ${exampleName}`, 'info');
                setTimeout(() => {
                    document.getElementById('status-bar').classList.remove('show');
                }, 2000);
            }
        }

        // 清除输出
        function clearOutput() {
            document.getElementById('output').textContent = '输出已清除';
        }

        // 显示状态
        function showStatus(message, type) {
            const statusBar = document.getElementById('status-bar');
            statusBar.textContent = message;
            statusBar.className = `status-bar show ${type}`;
        }

        // 键盘快捷键
        document.getElementById('code-editor').addEventListener('keydown', (e) => {
            if (e.ctrlKey && e.key === 'Enter') {
                e.preventDefault();
                runCode();
            }
            
            // Tab 键支持
            if (e.key === 'Tab') {
                e.preventDefault();
                const start = e.target.selectionStart;
                const end = e.target.selectionEnd;
                const value = e.target.value;
                e.target.value = value.substring(0, start) + '    ' + value.substring(end);
                e.target.selectionStart = e.target.selectionEnd = start + 4;
            }
        });

        // 自动保存到 localStorage
        const editor = document.getElementById('code-editor');
        editor.addEventListener('input', () => {
            localStorage.setItem('saved-code', editor.value);
        });

        // 恢复保存的代码
        const savedCode = localStorage.getItem('saved-code');
        if (savedCode) {
            editor.value = savedCode;
        }

        // 页面加载时初始化
        window.addEventListener('load', () => {
            loadPyodide();
        });

        // 防止意外关闭
        window.addEventListener('beforeunload', (e) => {
            const code = document.getElementById('code-editor').value;
            if (code.trim().length > 0) {
                e.preventDefault();
                e.returnValue = '';
            }
        });
    </script>
</body>
</html>

